package com.aeoj.clientmanagement.service.impl;

import com.aeoj.clientmanagement.constant.PkConstant;
import com.aeoj.clientmanagement.domain.user.SysUser;
import com.aeoj.clientmanagement.domain.userscore.dto.UserScoreDTO;
import com.aeoj.clientmanagement.domain.userscore.vo.UserScoreVO;
import com.aeoj.clientmanagement.enums.userscore.RankEnum;
import com.aeoj.clientmanagement.service.SysUserService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.aeoj.clientmanagement.domain.userscore.UserScore;
import com.aeoj.clientmanagement.service.UserScoreService;
import com.aeoj.clientmanagement.mapper.UserScoreMapper;
import jakarta.annotation.Resource;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ZSetOperations;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
* @author 20620
* @description 针对表【aeoj_user_score(用户积分表)】的数据库操作Service实现
* @createDate 2025-04-23 12:47:05
*/
@Service
public class UserScoreServiceImpl extends ServiceImpl<UserScoreMapper, UserScore>
    implements UserScoreService{
    @Resource
    private UserScoreMapper userScoreMapper;
    @Resource
    private RedisTemplate redisTemplate;
    @Resource
    private SysUserService sysUserService;

    @Override
    public List<UserScoreDTO> listRanking() {
        return userScoreMapper.listRanking();
    }

    @Override
    public List<UserScoreVO> listRankingByRedis(Integer pageNum, Integer pageSize) {
        Set<ZSetOperations.TypedTuple<UserScoreDTO>> set = new HashSet();
        try {
            ZSetOperations zSetOperations = redisTemplate.opsForZSet();
            int start = (pageNum - 1) * pageSize;
            int end = start + pageSize - 1;
            set = zSetOperations.reverseRangeWithScores(PkConstant.PK_RANKING_REDIS_KEY, start, end);
        } catch (Exception e) {
            log.error("Redis 出现问题：{}", e);
            return null;
        }
        List<UserScoreVO> res = new ArrayList<>();
        if (set != null) {
            for (ZSetOperations.TypedTuple<UserScoreDTO> tuple : set) {
                UserScoreDTO userScoreDTO = tuple.getValue();
                if (userScoreDTO != null) {
                    UserScoreVO userScoreVO = new UserScoreVO();
                    userScoreVO.setUserId(userScoreDTO.getUserId());
                    userScoreVO.setRankName(RankEnum.getByCode(userScoreDTO.getRankName()).getName());
                    userScoreVO.setScore(userScoreDTO.getScore());
                    userScoreVO.setWinMatches(userScoreDTO.getWinMatches());
                    userScoreVO.setLoseMatches(userScoreDTO.getLoseMatches());
                    userScoreVO.setId(userScoreDTO.getId());
                    userScoreVO.setUsername(userScoreDTO.getUsername());
                    userScoreVO.setAvatar(userScoreDTO.getAvatar());
                    userScoreVO.setDescription(userScoreDTO.getDescription());
                    userScoreVO.setTotalMatches(userScoreDTO.getTotalMatches());
                    res.add(userScoreVO);
                }
            }
        }
        return res;
    }

    @Override
    public List<UserScoreDTO> listRanking(Integer pageNum, Integer pageSize) {
        Integer start = (pageNum - 1) * pageSize;
        Integer end = start + pageSize - 1;
        return userScoreMapper.listRankingByPage(start, end);
    }

    @Override
    public int updateUserScoreByUserId(Long userId, Integer score) {
        QueryWrapper<UserScore> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_id", userId);
        UserScore userScore = userScoreMapper.selectOne(queryWrapper);
        if (score > 0)
            userScore.setWinMatches(userScore.getWinMatches() + 1);
        else if (score < 0)
            userScore.setLoseMatches(userScore.getLoseMatches() + 1);
        userScore.setTotalMatches(userScore.getTotalMatches() + 1);
        long newScore = userScore.getScore() + score;
        userScore.setScore(newScore);
        userScore.setRankName(RankEnum.getByScore(newScore).getCode());
        return userScoreMapper.updateById(userScore);
    }

    @Override
    public UserScoreVO getUserScoreByUserId(Long userId) {
        QueryWrapper<UserScore> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_id", userId);
        UserScore userScore = this.getOne(queryWrapper);
        if (userScore == null) {
            userScore = UserScore.builder()
                    .score(PkConstant.PK_DEFAULT_SCORE)
                    .userId(userId)
                    .rankName(RankEnum.LEVEL1.getCode())
                    .winMatches(0)
                    .loseMatches(0)
                    .totalMatches(0)
                    .build();
            boolean save = this.save(userScore);
            if (!save) {
                log.error("用户积分初始化失败");
            }
        }

        UserScoreVO userScoreVO = UserScoreVO.toUserScoreVO(userScore);
        SysUser user = sysUserService.getById(userId);
        userScoreVO.setUsername(user.getNickName());
        userScoreVO.setAvatar(user.getAvatar());

        List<UserScoreVO> list = this.listRankingByRedis(1, 1000);
        for (int i = 1; i <= list.size(); i++) {
            if (list.get(i - 1).getUserId().equals(user.getUserId())) {
                userScoreVO.setRank(i + "");
                break;
            }
        }

        return userScoreVO;
    }
}




